﻿/**************************************************************
 *
 * 唯一标识：e923503a-32db-4fef-a09e-abb51fe4f95e
 * 命名空间：Microsoft.Extensions.DependencyInjection
 * 创建时间：2024/6/21 11:08:20
 * 机器名称：DESKTOP-HJ4OAG9
 * 创建者：CocoYuan
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Sgr.Data;
using Sgr.Generator;
using Sgr.Generator.Segment;
using Sgr.Generator.Segment.Sead;
using Sgr.Generator.Segment.Storage;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddSgrGenerator(this IServiceCollection services)
        {
            services.AddOptions<SegmentNumIdGeneratorOptions>()
                .BindConfiguration("Sgr:SegmentNum")
                .Validate(opt =>
                {
                    if (opt.MaxStepUpperBound < 100)
                        return false;

                    if (opt.MaxStepUpperBound < 100)
                        return false;

                    if (opt.BufferRwTimeout <= 0 || opt.BufferRwTimeout > 1000)
                        return false;

                    if (opt.GetId_Attempt_Limit <= 0 || opt.GetId_Attempt_Limit > 1024)
                        return false;

                    if (opt.GetId_TimeOut_Milliseconds <= 0 || opt.GetId_TimeOut_Milliseconds > 5000)
                        return false;

                    if (opt.UpdateSegmentFromDb_TimeOut_Milliseconds <= 0 || opt.UpdateSegmentFromDb_TimeOut_Milliseconds > 5000)
                        return false;

                    if (opt.Circuit_Reset_Seconds <= 0)
                        return false;

                    if (opt.ErrorThresholdBeforeTrip <= 0)
                        return false;

                    if (opt.UpdateIntervalSeconds < 0)
                        return false;

                    return true;
                }, "号段生成器配置项设置错误");

            //Segment
            services.TryAddEnumerable(ServiceDescriptor.Singleton<ISegmentProvider, DefaultSegmentProvider>());
            services.TryAddEnumerable(ServiceDescriptor.Transient<IDataBaseInitialize, SegmentDataBaseInitialize>());

            services.TryAddSingleton<ISegmentEntityDataStorage, SegmentEntityDataStorage>();

            if (services.Any(f => f.ServiceType == typeof(ISegmentNumIdGenerator)))
                services.Replace(ServiceDescriptor.Singleton<ISegmentNumIdGenerator, SegmentNumIdGenerator>());
            else
                services.TryAddSingleton<ISegmentNumIdGenerator, SegmentNumIdGenerator>();

            //if (services.Any(f => f.ServiceType == typeof(ISegmentNumIdGenerator)))
            //    services.Replace(ServiceDescriptor.Singleton<ISegmentNumIdGenerator>(sp =>
            //    {
            //        return CreateSegmentNumIdGenerator(sp);
            //    }));
            //else
            //    services.AddSingleton<ISegmentNumIdGenerator>(sp =>
            //    {
            //        return CreateSegmentNumIdGenerator(sp);
            //    });

            ////Snowflake
            //services.TryAddTransient<IWorkIdRegister, DefaultWorkIdRegister>();
            //services.AddOptions<IdGeneratorOptions>()
            //    .BindConfiguration("ThirdParty:Yitter_IdGenerator");

            ////.PostConfigure(opt =>
            ////{
            ////    //从环境变量中获取 WorkerId
            ////    string? workerId = Environment.GetEnvironmentVariable("SGR_SNOWFLAKE_WORKID");
            ////    if(ushort.TryParse(workerId, out ushort id))
            ////    {
            ////        opt.WorkerId = id;
            ////    }
            ////});

            //if (services.Any(f => f.ServiceType == typeof(INumberIdGenerator)))
            //    services.Replace(ServiceDescriptor.Singleton<INumberIdGenerator, YitterIdGenerator>());
            //else
            //    services.AddSingleton<INumberIdGenerator, YitterIdGenerator>();

            return services;
        }

        //private static SegmentNumIdGenerator CreateSegmentNumIdGenerator(IServiceProvider sp)
        //{
        //    ISegmentEntityDataStorage genSegmentDataStorage = sp.GetRequiredService<ISegmentEntityDataStorage>();
        //    ILogger<SegmentNumIdGenerator> logger = sp.GetRequiredService<ILogger<SegmentNumIdGenerator>>();
        //    IOptions<SegmentNumIdGeneratorOptions> option = sp.GetRequiredService<IOptions<SegmentNumIdGeneratorOptions>>();

        //    SegmentNumIdGenerator segmentNumIdGenerator = new SegmentNumIdGenerator(genSegmentDataStorage, logger, option);

        //    //AsyncHelper.RunSync(() => segmentNumIdGenerator.InitAsync());
        //    //segmentNumIdGenerator.InitAsync().ConfigureAwait(false).GetAwaiter().GetResult();

        //    return segmentNumIdGenerator;
        //}
    }
}